<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>command模式 &mdash; programming v0.1 documentation</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="top" title="programming v0.1 documentation" href="../index.html" />
    <link rel="up" title="设计模式学习笔记" href="index.html" />
    <link rel="next" title="adapter模式" href="adapter.html" />
    <link rel="prev" title="singleton模式" href="singleton.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="adapter.html" title="adapter模式"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="singleton.html" title="singleton模式"
             accesskey="P">上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" accesskey="U">设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="command">
<h1>command模式<a class="headerlink" href="#command" title="永久链接至标题">¶</a></h1>
<div class="section" id="id1">
<span id="index-2"></span><span id="id2"></span><h2>command模式定义<a class="headerlink" href="#id1" title="永久链接至标题">¶</a></h2>
<p><strong>The Command Pattern</strong> encapsulates a request as an object, thereby letting you
parameterize other objects with different requests, queue or log requests, and
support undoable operations.</p>
<p><strong>命令模式</strong> 将一个请求封装为一个对象, 因此使得你可以使用不同的请求来参数化其它的对象,
对请求进行排队或者对请求进行日志,并且支持撤销操作.</p>
<p><strong>当需要将请求的对象与执行请求的对象去耦合时,请使用命令模式</strong>.</p>
</div>
<div class="section" id="id3">
<h2>问题描述<a class="headerlink" href="#id3" title="永久链接至标题">¶</a></h2>
<p>引入 <em>command</em> 模式:</p>
<img alt="../_images/command_exp.png" src="../_images/command_exp.png" />
<p><strong>command</strong> 模式的类图如下:</p>
<img alt="../_images/command_class.png" src="../_images/command_class.png" />
</div>
<div class="section" id="id4">
<h2>具体代码<a class="headerlink" href="#id4" title="永久链接至标题">¶</a></h2>
<p>下载请点击 <a href="../_downloads/command.cpp"><strong class="xref">这里</strong></a></p>
<div class="highlight-c++"><table class="highlighttable"><tr><td class="linenos"><pre>  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161</pre></td><td class="code"><div class="highlight"><pre><span class="cp">#include &lt;iostream&gt;</span>
<span class="cp">#include &lt;string&gt;</span>
<span class="cp">#include &lt;vector&gt;</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Command</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="k">virtual</span> <span class="kt">void</span> <span class="n">execute</span><span class="p">(){}</span>
        <span class="k">virtual</span> <span class="kt">void</span> <span class="n">undo</span><span class="p">(){}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">Light</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="kt">void</span> <span class="n">on</span><span class="p">(){</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The light is on&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;}</span>
        <span class="kt">void</span> <span class="n">off</span><span class="p">(){</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The light is off&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">Fan</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">HIGH</span><span class="o">=</span><span class="mi">3</span><span class="p">;</span>
        <span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">MEDIUM</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
        <span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">LOW</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
        <span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">OFF</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="kt">int</span> <span class="n">speed</span><span class="p">;</span>
        <span class="kt">void</span> <span class="n">show_current_speed</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;Current Speed of fan:&quot;</span><span class="o">&lt;&lt;</span><span class="n">getSpeed</span><span class="p">()</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kt">void</span> <span class="n">high</span><span class="p">(){</span><span class="n">speed</span><span class="o">=</span><span class="n">HIGH</span><span class="p">;</span><span class="n">show_current_speed</span><span class="p">();}</span>
        <span class="kt">void</span> <span class="n">medium</span><span class="p">(){</span><span class="n">speed</span><span class="o">=</span><span class="n">MEDIUM</span><span class="p">;</span><span class="n">show_current_speed</span><span class="p">();}</span>
        <span class="kt">void</span> <span class="n">low</span><span class="p">(){</span><span class="n">speed</span><span class="o">=</span><span class="n">LOW</span><span class="p">;</span><span class="n">show_current_speed</span><span class="p">();}</span>
        <span class="kt">void</span> <span class="n">off</span><span class="p">(){</span><span class="n">speed</span><span class="o">=</span><span class="n">OFF</span><span class="p">;</span><span class="n">show_current_speed</span><span class="p">();}</span>
        <span class="kt">int</span> <span class="n">getSpeed</span><span class="p">(){</span><span class="k">return</span> <span class="n">speed</span><span class="p">;}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">FanHighCommand</span><span class="o">:</span><span class="k">public</span> <span class="n">Command</span>
<span class="p">{</span>
    <span class="k">private</span><span class="o">:</span>
        <span class="n">Fan</span><span class="o">*</span> <span class="n">fan</span><span class="p">;</span>
        <span class="kt">int</span> <span class="n">prevSpeed</span><span class="p">;</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">FanHighCommand</span><span class="p">(</span><span class="n">Fan</span><span class="o">*</span> <span class="n">fan</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">fan</span> <span class="o">=</span> <span class="n">fan</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">execute</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">prevSpeed</span> <span class="o">=</span> <span class="n">fan</span><span class="o">-&gt;</span><span class="n">getSpeed</span><span class="p">();</span>
            <span class="n">fan</span><span class="o">-&gt;</span><span class="n">high</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">undo</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">switch</span><span class="p">(</span><span class="n">prevSpeed</span><span class="p">)</span>
            <span class="p">{</span>
                <span class="k">case</span> <span class="n">Fan</span><span class="o">::</span><span class="nl">HIGH:</span>
                    <span class="n">fan</span><span class="o">-&gt;</span><span class="n">high</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="k">case</span> <span class="n">Fan</span><span class="o">::</span><span class="nl">MEDIUM:</span>
                    <span class="n">fan</span><span class="o">-&gt;</span><span class="n">medium</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="k">case</span> <span class="n">Fan</span><span class="o">::</span><span class="nl">LOW:</span>
                    <span class="n">fan</span><span class="o">-&gt;</span><span class="n">low</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="k">case</span> <span class="n">Fan</span><span class="o">::</span><span class="nl">OFF:</span>
                    <span class="n">fan</span><span class="o">-&gt;</span><span class="n">off</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="k">default</span><span class="o">:</span>
                    <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">LightOffCommand</span><span class="o">:</span><span class="k">public</span> <span class="n">Command</span>
<span class="p">{</span>
    <span class="k">private</span><span class="o">:</span>
        <span class="n">Light</span><span class="o">*</span> <span class="n">light</span><span class="p">;</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">LightOffCommand</span><span class="p">(</span><span class="n">Light</span><span class="o">*</span> <span class="n">light</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">light</span> <span class="o">=</span> <span class="n">light</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">execute</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">light</span><span class="o">-&gt;</span><span class="n">off</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">undo</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">light</span><span class="o">-&gt;</span><span class="n">on</span><span class="p">();</span>
        <span class="p">}</span>
<span class="p">};</span>


<span class="k">class</span> <span class="nc">LightOnCommand</span><span class="o">:</span><span class="k">public</span> <span class="n">Command</span>
<span class="p">{</span>
    <span class="k">private</span><span class="o">:</span>
        <span class="n">Light</span><span class="o">*</span> <span class="n">light</span><span class="p">;</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">LightOnCommand</span><span class="p">(</span><span class="n">Light</span><span class="o">*</span> <span class="n">light</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">light</span> <span class="o">=</span> <span class="n">light</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">execute</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">light</span><span class="o">-&gt;</span><span class="n">on</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">undo</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">light</span><span class="o">-&gt;</span><span class="n">off</span><span class="p">();</span>
        <span class="p">}</span>
<span class="p">};</span>
<span class="k">class</span> <span class="nc">NoCommand</span><span class="o">:</span><span class="k">public</span> <span class="n">Command</span>  <span class="c">//as the default command, which no other commands suit</span>
<span class="p">{</span>
<span class="p">};</span>


<span class="k">class</span> <span class="nc">SimpleRemoteControl</span>
<span class="p">{</span>
    <span class="k">private</span><span class="o">:</span>
        <span class="n">vector</span><span class="o">&lt;</span><span class="n">Command</span> <span class="o">*&gt;</span> <span class="n">onCommands</span><span class="p">;</span>
        <span class="n">vector</span><span class="o">&lt;</span><span class="n">Command</span> <span class="o">*&gt;</span> <span class="n">offCommands</span><span class="p">;</span>
        <span class="n">Command</span> <span class="o">*</span><span class="n">undoCommand</span><span class="p">;</span>

    <span class="k">public</span><span class="o">:</span>
        <span class="n">SimpleRemoteControl</span><span class="p">(){}</span>

        <span class="kt">void</span> <span class="n">setCommand</span><span class="p">(</span><span class="n">Command</span><span class="o">*</span> <span class="n">onCommand</span><span class="p">,</span> <span class="n">Command</span><span class="o">*</span> <span class="n">offCommand</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">onCommands</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">onCommand</span><span class="p">);</span>
            <span class="n">offCommands</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">offCommand</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">onButtonWasPressed</span><span class="p">(</span><span class="kt">int</span> <span class="n">which</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">onCommands</span><span class="p">[</span><span class="n">which</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">execute</span><span class="p">();</span>
            <span class="n">undoCommand</span> <span class="o">=</span> <span class="n">onCommands</span><span class="p">[</span><span class="n">which</span><span class="p">];</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">offButtonWasPressed</span><span class="p">(</span><span class="kt">int</span> <span class="n">which</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">offCommands</span><span class="p">[</span><span class="n">which</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">execute</span><span class="p">();</span>
            <span class="n">undoCommand</span> <span class="o">=</span> <span class="n">offCommands</span><span class="p">[</span><span class="n">which</span><span class="p">];</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">undoButtonPressed</span><span class="p">()</span>    <span class="c">//invoke the undo action</span>
        <span class="p">{</span>
            <span class="n">undoCommand</span><span class="o">-&gt;</span><span class="n">execute</span><span class="p">();</span>
        <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">SimpleRemoteControl</span> <span class="n">remote</span><span class="p">;</span>
    <span class="n">LightOnCommand</span> <span class="n">lightOn</span><span class="p">(</span><span class="k">new</span> <span class="n">Light</span><span class="p">());</span>
    <span class="n">LightOffCommand</span> <span class="n">lightOff</span><span class="p">(</span><span class="k">new</span> <span class="n">Light</span><span class="p">());</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">setCommand</span><span class="p">(</span><span class="o">&amp;</span><span class="n">lightOn</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">lightOff</span><span class="p">);</span>
    <span class="n">FanHighCommand</span> <span class="n">fanHigh</span><span class="p">(</span><span class="k">new</span> <span class="n">Fan</span><span class="p">());</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">setCommand</span><span class="p">(</span><span class="o">&amp;</span><span class="n">fanHigh</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">fanHigh</span><span class="p">);</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">onButtonWasPressed</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">offButtonWasPressed</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">offButtonWasPressed</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">remote</span><span class="p">.</span><span class="n">undoButtonPressed</span><span class="p">();</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
        
</pre></div>
</td></tr></table></div>
<p>输出结果为:</p>
<div class="highlight-python"><pre>The light is on
The light is off
Current Speed of fan:3
Current Speed of fan:3  // the last action</pre>
</div>
</div>
<div class="section" id="id5">
<h2>面对新的需要<a class="headerlink" href="#id5" title="永久链接至标题">¶</a></h2>
<p>对于新的请求,只需如下操作即可:</p>
<ul class="simple">
<li>继承 <strong>Command</strong> 类</li>
<li>实现其中的接口</li>
</ul>
</div>
<div class="section" id="id6">
<h2>更多注意<a class="headerlink" href="#id6" title="永久链接至标题">¶</a></h2>
<p>在上面的类图(及实现)中,其中最核心的 <strong>去耦合</strong> 部件即是 <strong>Command</strong> 类.</p>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>关于 <strong>为请求排队</strong>, 例如 <strong>调度器</strong>, <strong>线程池</strong>, <strong>事件队列</strong> 等.</p>
<img alt="../_images/request_queue.png" src="../_images/request_queue.png" />
<p class="last">其中,事件队列与执行操作的对象是完全 <strong>去耦合</strong> 的.</p>
</div>
</div>
<div class="section" id="id7">
<h2>参考更多<a class="headerlink" href="#id7" title="永久链接至标题">¶</a></h2>
<ol class="arabic simple">
<li><a class="reference external" href="http://en.wikipedia.org/wiki/Command_pattern">Command_Pattern</a></li>
</ol>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference external" href="">command模式</a><ul>
<li><a class="reference external" href="#id1">command模式定义</a></li>
<li><a class="reference external" href="#id3">问题描述</a></li>
<li><a class="reference external" href="#id4">具体代码</a></li>
<li><a class="reference external" href="#id5">面对新的需要</a></li>
<li><a class="reference external" href="#id6">更多注意</a></li>
<li><a class="reference external" href="#id7">参考更多</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="singleton.html"
                                  title="上一章">singleton模式</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="adapter.html"
                                  title="下一章">adapter模式</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../_sources/designpattern/command.txt"
                     rel="nofollow">显示源代码</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>快速搜索</h3>
              <form class="search" action="../search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="搜索" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              输入相关的模块，术语，类或者函数名称进行搜索
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="adapter.html" title="adapter模式"
             >下一页</a> |</li>
        <li class="right" >
          <a href="singleton.html" title="singleton模式"
             >上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" >设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 版权所有 2009, zhutao.iscas@gmail.com.
      使用 <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
    </div>
  </body>
</html>